#ifndef BENCHMARK_HPP
#define BENCHMARK_HPP

#include "chrono_timer.hpp"

#include <chrono>
#include <random>

#if _MSC_VER >= 1400
#define NOINLINE(s) __declspec(noinline) s
#else
#define NOINLINE(s) s __attribute__ ((noinline))
#endif

// Globals
chrono_timer g_timer;

// Constants
constexpr std::size_t c_payload = 2;
constexpr std::size_t c_max_con = 9001;

// General typedefs
typedef std::minstd_rand Rng_t;
typedef std::uniform_int_distribution<std::size_t> Eng_t;

// Unit related typedefs
typedef std::chrono::seconds Limit_u;
typedef std::chrono::nanoseconds Timer_u;
typedef std::chrono::duration<double, std::milli> Delta_u;

// Functors
struct IncrementFill
{
    std::size_t i;
    IncrementFill ( ) : i(0) { }
    std::size_t operator()() { return i++; }
};

// Global Free Functions
std::size_t round_2_up(std::size_t n)
{
    if (n & (n - 1))
    {
        do
        {
            n = n & (n - 1);
        }
        while (n & (n - 1));

        return n << 1;
    }
    return n;
}

std::size_t round_2_down(std::size_t n)
{
    if (n & (n - 1))
    {
        do
        {
            n = n & (n - 1);
        }
        while (n & (n - 1));

        return n;
    }
    return n;
}

#endif // BENCHMARK_HPP
